#include "gameField.h"


gameField::gameField(void)
{
}

gameField::gameField(int lenx, int leny)
{
	length_x = lenx;
	length_y = leny;
	for (int i = 0; i<lenx;i++){
		for (int j= 0; j<leny;j++){
			collidableField[i][j] = 32;
			LOSField[i][j] = 176;
		}
	}
	drawGameBoard();
}
void gameField::drawGameBoard()
{
	int i = 0;
	int j = 0;
	for (i = 1; i<2*length_x+1+1; i++)
	{
		for (j=1; j<2*length_y+1+1; j++)
		{
			if (i % 2 != 0 || j % 2 != 0)
			{
				COORD p = {i, j};
				SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),p);
				//Bra!
				if (i == 1)
				{
					if (j == 1)
					{
						cout << char(218);
					}
					else if (j == (2*length_y+1))
					{
						cout << char(192);
					}
					else
					{
						if (j%2 != 0)
						{
							cout << char(195);
						}
						else
						{
							cout<< char(179);
						}
					}
				}
				//Bra!
				else if (i == (2*length_x+1))
				{
					if (j == 1)
					{
						cout << char(191);
					}
					else if (j==(2*length_y+1))
					{
						cout << char(217);
					}
					else
					{
						if (j%2 != 0)
						{
							cout << char(180);
						}
						else
						{
							cout<< char(179);
						}
					}
				}
				else
				{
					//Bra!
					if (j==1)
					{
						if (i%2 != 0)
						{
							cout << char(194);
						}
						else
						{
							cout<< char(196);
						}
					}
					//Bra!
					else if (j== (2*length_y+1))
					{
						if (i%2 != 0)
						{
							cout << char(193);
						}
						else
						{
							cout<< char(196);
						}
					}
					else
					{
						if (i % 2 == 1 && j % 2 == 1)
						{
							cout << char(197);

						}
						else if (i%2 == 1)
						{
							cout << char(179);
						}
						else
						{
							cout << char(196);
						}
					}
				}
			}
			else{
				COORD p = {i, j};
				SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),p);
				cout << char(176);
			}
			
		}
	}
}
void gameField::addObject(collidable* c)
{
	collidables.push_back(c);
}
int gameField::removeObject(collidable* c)
{
	return 1;
}

void gameField::reDraw(){
	
	updateCollidableField();
	for (auto it = collidables.begin(); it < collidables.end();it++){
		collidable* c = *it;
		if (c->getType() == 0){
			updateLOS(c);
		}
	}

	for (auto it = collidables.begin(); it < collidables.end();it++){
		collidable* c = *it;
		if (c->getType() == 0){
			for (int i = max(c->getX()-6,0); i< min(c->getX()+7,length_x); i++){
				for (int j = max(c->getY()-6,0); j< min(c->getY()+7,length_y); j++){
					COORD p = {i*2+2, j*2+2};
					SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),p);
					cout << char(LOSField[i][j]);
				}
			}
		}
	}

}


int gameField::moveObject(collidable* c, int i)
{
	int curPosX = c->getX();
	int curPosY = c->getY();
	int lsb = i & 0x000F;
	int msb = i & 0xF000;
	if (msb == 0x1000){
		switch (lsb){
		case 1: //Left
			if (curPosX > 0){
				COORD p1 = {curPosX*2+2, curPosY*2+2};	
				COORD p2 = {(curPosX-1)*2+2, curPosY*2+2};
				char buf[2];
				COORD coord = {0,0};
				DWORD num_read;
				ReadConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), (LPTSTR) buf, (DWORD) 1, p2, (LPDWORD) &num_read);
				if ( buf[0] == ' '){
					c->setX(curPosX-1);
					return 0x1009; //SUCCESS
				}
				else
				{
					for (auto it = collidables.begin(); it < collidables.end();it++){
						collidable* c2 = *it;
						if (curPosX-1 == c2->getX() && curPosY == c2->getY())
						{
							return c2->animate(c,0x2000);
						}
					}
				}
			}
			break;
		case 2: //Right
			if (curPosX < length_x-1){
				COORD p1 = {curPosX*2+2, curPosY*2+2};	
				COORD p2 = {(curPosX+1)*2+2, curPosY*2+2};
				char buf[2];
				COORD coord = {0,0};
				DWORD num_read;
				ReadConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), (LPTSTR) buf, (DWORD) 1, p2, (LPDWORD) &num_read);
				if ( buf[0] == ' '){
					c->setX(curPosX+1);
					return 0x1009; //SUCCESS
				}
				else
				{
					for (auto it = collidables.begin(); it < collidables.end();it++){
						collidable* c2 = *it;
						if (curPosX+1 == c2->getX() && curPosY == c2->getY())
						{
							return c2->animate(c,0x2000);
						}
					}
				}
			}
			break;
		case 3: //Up
			if (curPosY > 0){
				COORD p1 = {curPosX*2+2, curPosY*2+2};	
				COORD p2 = {(curPosX)*2+2, (curPosY-1)*2+2};
				char buf[2];
				COORD coord = {0,0};
				DWORD num_read;
				ReadConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), (LPTSTR) buf, (DWORD) 1, p2, (LPDWORD) &num_read);
				if ( buf[0] == ' '){
					c->setY(curPosY-1);
					return 0x1009; //SUCCESS
				}
				else
				{
					for (auto it = collidables.begin(); it < collidables.end();it++){
						collidable* c2 = *it;
						if (curPosX == c2->getX() && curPosY-1 == c2->getY())
						{
							return c2->animate(c,0x2000);
						}
					}
				}
			}
			break;
		case 4: //Down
			if (curPosY < length_y-1){
				COORD p1 = {curPosX*2+2, curPosY*2+2};	
				COORD p2 = {(curPosX)*2+2, (curPosY+1)*2+2};
				char buf[2];
				COORD coord = {0,0};
				DWORD num_read;
				ReadConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), (LPTSTR) buf, (DWORD) 1, p2, (LPDWORD) &num_read);
				if ( buf[0] == ' '){
					c->setY(curPosY+1);
					return 0x1009; //SUCCESS
				}
				else
				{
					for (auto it = collidables.begin(); it < collidables.end();it++){
						collidable* c2 = *it;
						if (curPosX == c2->getX() && curPosY+1 == c2->getY())
						{
							return c2->animate(c,0x2000);
						}
					}
				}
			}
			break;
		case 0:
			return 0x1009;
		}
	}
	return 0x6666;
}

COORD gameField::getFieldSize()
{
	COORD  c = {length_x, length_y};
	return c;
}

void gameField::updateLOS(collidable *c){
	int x = c->getX();
	int y = c->getY();
	int i = 0, j = 0;
	
	for (i = 0; i<length_x; i++){
		for (j = 0; j<length_y;j++){
			LOSField[i][j] = 176;
		}
	}
	for (i = 0; i<length_x; i++){
		for (j = 0; j<length_y;j++){
			double distance = sqrt((i-x)*(i-x)+(j-y)*(j-y));
			if (distance <= 5){
				LOSField[i][j] = collidableField[i][j];
			}
		}
	}
}

void gameField::updateCollidableField(){
	
	int i = 0, j = 0;
	
	for (i = 0; i<length_x; i++){
		for (j = 0; j<length_y;j++){
			collidableField[i][j] = 32;
		}
	}
	for (auto it = collidables.begin(); it < collidables.end();it++){
		collidable* c1 = *it;
		collidableField[c1->getX()][c1->getY()] = c1->getSign();
	}
}

int gameField::getLOS(int xpos, int ypos){
	static int arr[100];
	for (int i = max(xpos-5,0); i< min(xpos+6,length_x); i++){
		for (int j = max(ypos-5,0); j< min(ypos+6,length_y); j++){
			arr[j+i*10] = collidableField[i][j];
		}
	}
	return arr[0];
}

gameField::~gameField(void)
{
}
